<?
/*! \brief Builds command from web service XML 
 * 
 */
class CommandBuilder
{
	protected $_service, $_command, $_rootDir, $_outputDir, $_workingDir, 
		$_outputFile;
	
	public function __construct($service)
	{
		$this->_service = $service;	
		$this->build();
	}
	
	private function build()
	{
		//setup output directory
		$this->_rootDir = BASE_DIR
					."/tmp/fileserv/".date('YmdHms').".".rand(0,9999);
		$this->_outputDir = $this->_rootDir.'/output';
		$this->_workingDir = $this->_rootDir.'/working';
	
		//make your directories
		mkdir($this->_rootDir, 0777, true);
		mkdir($this->_outputDir, 0777, true);
		mkdir($this->_workingDir, 0777, true);
		
		//begin building command
		$this->laborer($this->_service->getSimple()->interpreter);
		$this->laborer($this->_service->getSimple()->binary);
		
		//inputs -- order can be of importance
		if(isset($this->_service->getSimple()->inputs))
		{
			foreach($this->_service->getSimple()->inputs->input as $input)
			{
				switch($input->type)
				{
					case 'file':
						$index = str_replace("-", "", $input->qualifier);
		
						if($_FILES[$index]['size'] > 0)
						{
							$fileName = $this->_workingDir.'/'.
								$_FILES[$index]['name'];
							move_uploaded_file($_FILES[$index]['tmp_name'], 
								$fileName);
							$pos = strpos($index,'operand');
							if($pos === false)
								$this->laborer($input->qualifier." ".
									escapeshellarg($fileName));
							else
								$this->laborer("'".$fileName."'");
						}
						break;
					
					case 'argument':
						if($input->value != "")
							$this->laborer($input->qualifier." ".
								escapeshellarg(stripslashes($input->value)));
						break;
					
					case 'flag':
						if($input->enabled == "true")
							$this->laborer($input->qualifier);
						break;
					
					default:
						break;
				}
			}
		}

		//output
		if(isset($this->_service->getSimple()->output))
		{
			//what type of output
			switch($this->_service->getsimple()->output->type)
			{
				case "text":
					$this->_outputFile = "output.txt";
					$this->laborer($this->_service->getSimple()->output->qualifier.
						" ".escapeshellarg($this->getFullFile()).' 2>&1');
					break;
					
				case "prefix":
					$this->_outputFile = "output";
					$this->laborer($this->_service->getSimple()->output->qualifier.
						" ".escapeshellarg($this->getFullFile()).' 2>&1');
					$this->_outputFile = "output.zip";
					break;
					
				case "dicom":
					$this->_outputFile = "output.dcm";
					$this->laborer($this->_service->getSimple()->output->qualifier.
						" ".escapeshellarg($this->getFullFile()).' 2>&1');
					break;
					
				case "nifti-gz":
					$this->_outputFile = "output.nii.gz";
					$this->laborer($this->_service->getSimple()->output->qualifier.
						" ".escapeshellarg($this->getFullFile()).' 2>&1');
					break;
					
				case "stdout":
					$this->_outputFile = "output.txt";
					$this->laborer('> '. 
						escapeshellarg($this->getFullFile()) . 
							' 2>&1 || code=$? && cat ' . 
							escapeshellarg($this->getFullFile()).' && `exit $code`');
					break;
					
				case "directory":
					$this->_outputFile = "output.zip";
					$this->laborer($this->_service->getSimple()->output->qualifier.
						" ".escapeshellarg($this->_outputDir).' 2>&1');
					break;
					
				default:
					$this->_outputFile = "output.bin";
					$this->laborer($this->_service->getSimple()->output->qualifier.
						" ".escapeshellarg($this->getFullFile()).' 2>&1');
					break;
			}
		}
	}
	
	private function laborer($string)
	{
		//construct the command together
		if($this->_command != "")
			$this->_command = $this->_command." ".$string;
		else
			$this->_command = 'cd '.$this->_workingDir.' && '.$string;
	}
	
	public function setCommand($cmd)
	{
		$this->_command = $cmd;
	}
	
	public function getCommand()
	{
		return $this->_command;
	}
	
 	public function getDir($string)
	{
		switch($string)
		{
			case 'root':
				return $this->_rootDir;
				break;
			case 'output':
				return $this->_outputDir;
				break;
			case 'working':
				return $this->_workingDir;
				break;
		}
	}
	
	public function getOutputFile()
	{
		return $this->_outputFile;
	}
	
	public function getFullFile()
	{
		//*nix Specific
		return $this->_outputDir."/".$this->_outputFile;
	}
}
